home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1991
/
06
/
winclass.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-31
|
14KB
|
490 lines
/*--------------------------------------------------------
A tiny Windows class library
John Dimm, June 1991
--------------------------------------------------------*/
#include <windows.h>
#include <dos.h>
#include "winclass.h"
#define MAX_WINCLASSES 32
#define WW_POINTER 0
#define WP_POINTER_OFF "PDLG_OFF"
#define WP_POINTER_SEG "PDLG_SEG"
#define NEAR_POINTERS defined (__TINY__) || \
defined (__SMALL__) || \
defined (__MEDIUM__)
long FAR PASCAL _export ExportWndProc( HWND hWnd,
WORD iMessage, WORD wParam, LONG lParam );
long FAR PASCAL _export ExportDlgProc( HWND hDlg,
WORD iMessage, WORD wParam, LONG lParam );
struct MAIN
{
BOOLPROC InitInst[MAX_WINCLASSES];
BOOLPROC InitApp[MAX_WINCLASSES];
int nApp;
int nInst;
HANDLE hInstance;
HANDLE hPrevInstance;
int nCmdShow;
MAIN () {nApp = 0; nInst = 0;};
BOOL InitApplication();
BOOL InitInstance();
void Init (HANDLE hInstancePrm,
HANDLE hPrevInstancePrm, int nCmdShowPrm);
};
MAIN Main;
/*--------------------------------------------------------
Main Windows function
--------------------------------------------------------*/
#pragma argsused
int PASCAL WinMain( HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow )
{
MSG msg;
Main.Init (hInstance, hPrevInstance, nCmdShow);
if ( ! hPrevInstance )
if ( ! Main.InitApplication() )
return FALSE;
if ( ! Main.InitInstance() )
return FALSE;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam;
}
/*--------------------------------------------------------
Main stores the parameters passed to WinMain, and stores
the InitApplication and InitInstance procs for each
module.
--------------------------------------------------------*/
void MAIN::Init (HANDLE hInstancePrm,
HANDLE hPrevInstancePrm, int nCmdShowPrm)
{
hInstance = hInstancePrm;
hPrevInstance = hPrevInstancePrm;
nCmdShow = nCmdShowPrm;
}
/*--------------------------------------------------------
Each module registers its InitInstance function with
Main. The InitInstance functions will be called after the
instance handle is stored.
--------------------------------------------------------*/
void RegisterInstance ( BOOLPROC InitInstance )
{
if (Main.nInst < MAX_WINCLASSES)
Main.InitInst[Main.nInst++] = InitInstance;
}
/*--------------------------------------------------------
Call the InitInstance for each module.
--------------------------------------------------------*/
BOOL MAIN::InitInstance()
{
int i;
for (i=0; i<nInst; i++)
if ( ! InitInst[i]() )
return FALSE;
return TRUE;
}
/*--------------------------------------------------------
Same thing with the InitApplication functions.
--------------------------------------------------------*/
void RegisterApplication ( BOOLPROC InitApplication )
{
if (Main.nApp < MAX_WINCLASSES)
Main.InitApp[Main.nApp++] = InitApplication;
}
/*--------------------------------------------------------
Call the InitApplication for each module.
--------------------------------------------------------*/
BOOL MAIN::InitApplication()
{
int i;
for (i=0; i<nApp; i++)
if ( ! InitApp[i]() )
return FALSE;
return TRUE;
}
/*--------------------------------------------------------
Store the nCmdShow passed in from Windows.
--------------------------------------------------------*/
WINDOW::WINDOW()
{
nCmdShow = Main.nCmdShow;
}
/*--------------------------------------------------------
Register a class and create a window
--------------------------------------------------------*/
BOOL WINDOW::Make()
{
WNDCLASS WndClass;
CREATESTRUCT CreateStruct;
// Call the virtual function DefineWClass, allowing
// descendents of WINDOW to override the default values
// for the window class
DefineWClass( WndClass );
// Register the class, if it's not already registered
if ( ! GetClassInfo (Main.hInstance,
WndClass.lpszClassName,
(LPWNDCLASS)&WndClass) )
if ( ! RegisterClass( (LPWNDCLASS) &WndClass ) )
return FALSE;
// Allow descendents of WINDOW to change the default
// values for the create structure, by overriding
// DefineCreate().
DefineCreate( CreateStruct );
CreateWindow( CreateStruct.lpszClass,
CreateStruct.lpszName,
CreateStruct.style,
CreateStruct.x,
CreateStruct.y,
CreateStruct.cx,
CreateStruct.cy,
CreateStruct.hwndParent,
CreateStruct.hMenu,
CreateStruct.hInstance,
CreateStruct.lpCreateParams );
// The object's hWnd was set in ExportWndProc when the
// WM_CREATE was processed
if ( ! hWnd )
return FALSE;
Show();
Update();
return TRUE;
}
/*--------------------------------------------------------
Default window class
--------------------------------------------------------*/
void WINDOW::DefineWClass ( WNDCLASS &WndClass )
{
WndClass.style = NULL;
WndClass.lpfnWndProc = ExportWndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = sizeof( PWINDOW );
WndClass.hInstance = Main.hInstance;
WndClass.hIcon = NULL;
WndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
WndClass.hbrBackground = GetStockObject( WHITE_BRUSH );
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = GetClassName();
}
/*--------------------------------------------------------
Default create structure
--------------------------------------------------------*/
void WINDOW::DefineCreate ( CREATESTRUCT &CreateStruct )
{
CreateStruct.lpszClass = GetClassName();
CreateStruct.lpszName = GetWindowName();
CreateStruct.style = WS_OVERLAPPEDWINDOW;
CreateStruct.x = CW_USEDEFAULT;
CreateStruct.y = 0;
CreateStruct.cx = CW_USEDEFAULT;
CreateStruct.cy = 0;
CreateStruct.hwndParent = NULL;
CreateStruct.hMenu = NULL;
CreateStruct.hInstance = Main.hInstance;
CreateStruct.lpCreateParams = (LPSTR) this;
}
/*--------------------------------------------------------
Store pointer to window object
--------------------------------------------------------*/
inline void SetWndPointer( HWND hWnd, PWINDOW pWindow )
{
#if NEAR_POINTERS
SetWindowWord( hWnd, WW_POINTER, (WORD) pWindow );
#else
SetWindowLong( hWnd, WW_POINTER, (LONG) pWindow );
#endif
}
/*--------------------------------------------------------
Retrieve pointer to window object
--------------------------------------------------------*/
inline PWINDOW GetWndPointer( HWND hWnd )
{
#if NEAR_POINTERS
return (PWINDOW) GetWindowWord( hWnd, WW_POINTER );
#else
return (PWINDOW) GetWindowLong( hWnd, WW_POINTER );
#endif
}
/*--------------------------------------------------------
See the warning in Borland's example WHELLO.CPP. We get
the C++ window object pointer from the window extra
bytes, which are zero-initialized by Windows. So we can
safely assume any non-zero value is a pointer to a
window object. Unfortunately, the fact that extra bytes
are zero-initialized is undocumented. If this changes in
a future version of Windows, of if you don't like using
undocumented features, you can store the pointer in a
property rather than extra bytes. The property method
is completely standard and is implemented below for
dialog boxes.
--------------------------------------------------------*/
inline BOOL IsWndPointer ( PWINDOW pWindow)
{
return (pWindow != NULL);
}
/*--------------------------------------------------------
The WndProc called by Windows
--------------------------------------------------------*/
long FAR PASCAL _export ExportWndProc( HWND hWnd,
WORD iMessage, WORD wParam, LONG lParam )
{
PWINDOW pWindow = GetWndPointer( hWnd );
// If the window has already been initialized, call its
// WndProc
if ( IsWndPointer(pWindow) )
return pWindow->WndProc( iMessage, wParam, lParam );
// The window is not yet initialized.
if ( iMessage == WM_CREATE )
{
// Extract the pointer to the WINDOW object, placed by
// DefineCreate
pWindow =
(PWINDOW) ((LPCREATESTRUCT)lParam)->lpCreateParams;
// Store a pointer to the WINDOW object in the Window
// words
SetWndPointer( hWnd, pWindow );
// Store the window handle in the WINDOW object, so
// that it's available when the object processes the
// WM_CREATE message
pWindow->PutHandle ( hWnd );
// Pass the WM_CREATE message to the WINDOW object
return pWindow->WndProc( iMessage, wParam, lParam );
}
// The window is not yet initialized, but this is not
// the WM_CREATE message.
return DefWindowProc( hWnd, iMessage, wParam, lParam );
}
/*--------------------------------------------------------
Handle Windows messages, calling the appropriate virtual
functions. Add cases as needed.
--------------------------------------------------------*/
long WINDOW::WndProc( WORD iMessage,
WORD wParamPrm, LONG lParamPrm )
{
long retcode = TRUE;
// Save the wParam and lParam, so we don't have to pass
// them around as parameters
wParam = wParamPrm;
lParam = lParamPrm;
switch (iMessage)
{
case WM_CREATE:
Create();
break;
case WM_INITDIALOG:
InitDialog();
break;
case WM_COMMAND:
retcode = Command ();
break;
case WM_PAINT:
CallPaint();
break;
case WM_SIZE:
Size ();
break;
case WM_MOUSEMOVE:
MouseMove();
break;
case WM_LBUTTONDOWN:
LButtonDown();
break;
case WM_LBUTTONUP:
LButtonUp();
break;
case WM_TIMER:
Timer();
break;
case WM_DESTROY:
Destroy();
break;
default:
return DefaultProc( iMessage );
}
return retcode;
}
/*--------------------------------------------------------
Get the paint structure and call Paint
--------------------------------------------------------*/
void WINDOW::CallPaint ()
{
PAINTSTRUCT ps;
lpPaint = (LPPAINTSTRUCT) &ps;
BeginPaint ( hWnd, lpPaint );
Paint();
EndPaint ( hWnd, lpPaint );
}
/*--------------------------------------------------------
Set the windows words containing object pointer to NULL,
and set the window handle in the object to NULL. Any
further messages, such as WM_NCDESTROY, will be handled
by Windows.
--------------------------------------------------------*/
void WINDOW::Destroy()
{
SetWndPointer (hWnd, NULL);
hWnd = NULL;
}
/*--------------------------------------------------------
Make a modeless dialog box and wait until it's done
--------------------------------------------------------*/
int DIALOG::Make (HWND hParent)
{
FARPROC lpfnDlg;
int nResult;
lpfnDlg = MakeProcInstance((FARPROC)ExportDlgProc,
Main.hInstance);
nResult = DialogBoxParam (Main.hInstance,
GetTemplateName(),
hParent,
lpfnDlg,
(DWORD) this);
FreeProcInstance(lpfnDlg);
return nResult;
}
/*--------------------------------------------------------
Store pointer to dialog object
--------------------------------------------------------*/
inline void SetDlgPointer ( HWND hDlg, PDIALOG pDialog )
{
#if NEAR_POINTERS
SetProp ( hDlg, WP_POINTER_OFF, (HANDLE)pDialog );
#else
SetProp ( hDlg, WP_POINTER_SEG,
(HANDLE) FP_SEG(pDialog) );
SetProp ( hDlg, WP_POINTER_OFF,
(HANDLE) FP_OFF(pDialog) );
#endif
}
/*--------------------------------------------------------
Retrieve pointer to dialog object
--------------------------------------------------------*/
inline PDIALOG GetDlgPointer ( HWND hDlg )
{
#if NEAR_POINTERS
return (PDIALOG) GetProp ( hDlg, WP_POINTER_OFF );
#else
return
(PDIALOG) MK_FP ( GetProp ( hDlg, WP_POINTER_SEG ),
GetProp ( hDlg, WP_POINTER_OFF ) );
#endif
}
/*--------------------------------------------------------
Remove the property used to store the dialog object
pointer
--------------------------------------------------------*/
inline void DeleteDlgPointer ( HWND hDlg )
{
#if NEAR_POINTERS
RemoveProp ( hDlg, WP_POINTER_OFF );
#else
RemoveProp ( hDlg, WP_POINTER_SEG );
RemoveProp ( hDlg, WP_POINTER_OFF );
#endif
}
/*--------------------------------------------------------
The DlgProc called by Windows
--------------------------------------------------------*/
long FAR PASCAL _export ExportDlgProc( HWND hDlg,
WORD iMessage, WORD wParam, LONG lParam )
{
PDIALOG pDialog = GetDlgPointer ( hDlg );
// GetDlgPointer will return zero if the dialog is not yet
// initialized
if ( pDialog )
return pDialog->WndProc( iMessage, wParam, lParam );
if ( iMessage == WM_INITDIALOG )
{
pDialog = (PDIALOG) lParam;
SetDlgPointer ( hDlg, pDialog );
pDialog->PutHandle ( hDlg );
return pDialog->WndProc( iMessage, wParam, lParam );
}
}
/*--------------------------------------------------------
Remove the property used to store the pointer to the
C++ dialog object. From here on, GetDlgPointer will
return zero.
--------------------------------------------------------*/
void DIALOG::Destroy()
{
DeleteDlgPointer (hWnd);
hWnd = NULL;
}
/*--------------------------------------------------------
For unprocessed messages to dialog boxes, return FALSE
--------------------------------------------------------*/
#pragma argsused
long DIALOG::DefaultProc(WORD iMessage) { return FALSE; }